-- 为了增加代码的可读性, 专门倒腾个文件，真不赖啊
local w_mana = require "libs/worldmanager"       
local s_mana = require "libs/settingmanager"
local t_util = require "libs/tableutil"
local p_util = require "libs/playerutil"
local e_util = require "libs/entutil"


local s_data = s_mana:GetSettingLine("ECTRL")               -- 属性对值，立即存储
local w_data = w_mana:GetWorldDataMap("ECTRL")              -- 表名对表，按天存储  
local c_mana = {}

w_data.turn = w_data.turn or {}     -- 总开关
-- w_data[cate..slot] = {}          -- 每个slot的数据 prefab, xml, tex, value, lock

function c_mana:GetUIInitPos()
    local posx = s_data.posx
    local posy = s_data.posy
    if type(posx) == "number" and type(posy) == "number" then
        return {x = posx, y = posy}
    else
        return {}
    end
end

function c_mana:SetUIInitPos(pos)
    if not pos or not pos.x or not pos.y then return end
    s_data.posx = tonumber(string.format("%.2f", pos.x))
    s_data.posy = tonumber(string.format("%.2f", pos.y))
    s_mana:SaveSettingLine("ECTRL", s_data)
end

local slotdata = {}
function c_mana:SetSlotData(data)
    slotdata = t_util:MergeList(data or {})
end
function c_mana:GetSlotData()
    return slotdata or {}
end

-- 预测模式：默认开启
-- 预测术可能发生崩溃，要留接口
function c_mana:GetCompatibleMode()
    return s_data.pd_mode == nil and true or s_data.pd_mode
end
function c_mana:SetCompatibleMode(mode)
    s_data.pd_mode = mode == true
    s_mana:SaveSettingLine("ECTRL", s_data)
end
-- 右击复制到行走栏
function c_mana:GetRCMode()
    return s_data.rc_mode == nil and true or s_data.rc_mode
end
function c_mana:SetRCMode(mode)
    s_data.rc_mode = mode == true
    s_mana:SaveSettingLine("ECTRL", s_data)
end

-- 靠近攻击模式：默认开启
-- 在攻击范围内再切武器
function c_mana:GetAttackRangeMode()
    return s_data.rg_mode == nil and true or s_data.rg_mode
end
function c_mana:SetAttackRangeMode(mode)
    s_data.rg_mode = mode == true
    s_mana:SaveSettingLine("ECTRL", s_data)
end
-- UI隐藏:默认关闭
function c_mana:GetUIHide()
    return s_data.hide_mode
end
function c_mana:SetUIHide(mode)
    s_data.hide_mode = mode == true
    s_mana:SaveSettingLine("ECTRL", s_data)
end
-- 双击闪现：默认打开
function c_mana:GetDBClick()
    return s_data.db_mode == nil and true or s_data.db_mode
end
function c_mana:SetDBClick(mode)
    s_data.db_mode = mode == true
    s_mana:SaveSettingLine("ECTRL", s_data)
end

-- 对应攻击范围不敢存记忆力啊，那么多装备，都存一行的话怕挤爆，分行存的话，岂不蛮卡
local atkrange = {}
function c_mana:GetAtkRange(prefab)
    if type(prefab)~="string" then return 2 end
    local range = atkrange[prefab]
    if not range and self:GetCompatibleMode() then
        local copy = e_util:ClonePrefab(prefab).components.weapon
        range = copy and copy.attackrange and copy.attackrange + 2 or 2
    end
    return range or 2
end
function c_mana:SetAtkRange(prefab, range)
    if type(range) == "number" and type(prefab) == "string" then
        -- 这样可能会导致此件装备的攻击范围变化后仍然不生效，但是我怕切装备太快污染数据，有问题再说吧
        if not atkrange[prefab] then        
            atkrange[prefab] = range
        end
    end
end
function c_mana:GetBtnTurnValue(btnid)
    local val = w_data.turn[btnid]                          -- 默认turn是启用的
    return val == nil and true or val
end
-- 攻击冗余：关延迟
function c_mana:SetLeft_not_MV(num)
    num = tonumber(num)
    if type(num) == "number" then
        s_data.not_mv = num
        s_mana:SaveSettingLine("ECTRL", s_data)
    end
end
function c_mana:GetLeft_not_MV()
    local num = s_data.not_mv
    return type(num)=="number" and num or 1
end
-- 攻击冗余：开延迟
function c_mana:SetLeft_Has_MV(num)
    num = tonumber(num)
    if type(num) == "number" then
        s_data.has_mv = num
        s_mana:SaveSettingLine("ECTRL", s_data)
    end
end
function c_mana:GetLeft_Has_MV()
    local num = s_data.has_mv
    return type(num)=="number" and num or 0
end
-- 脱战范围
function c_mana:GetFightRange()
    local num = s_data.f_range
    return type(num)=="number" and num or 25
end
function c_mana:SetFightRange(num)
    num = tonumber(num)
    if type(num) == "number" then
        s_data.f_range = num
        s_mana:SaveSettingLine("ECTRL", s_data)
    end
end
-- 饥饿下限
function c_mana:GetStarveValue()
    local num = s_data.starve
    return type(num)=="number" and num or 0
end
function c_mana:SetStarveValue(num)
    num = tonumber(num)
    if type(num) == "number" then
        s_data.starve = num
        s_mana:SaveSettingLine("ECTRL", s_data)
    end
end

function c_mana:SetBtnTurnValue(btnid, value)
    w_data.turn[btnid] = value
end

function c_mana:GetBtnSlotData(cate, slot)
    local id = tostring(cate).."_"..tostring(slot)
    return t_util:MergeMap(w_data[id] or {})
end

function c_mana:SetBtnSlotData(cate, slot, data)
    local id = cate.."_"..slot
    w_data[id] = data
end

local dontimgban = {
    light = "slot",
    eat = "slot",
}

function c_mana:GetImgBan(cate, slot)
    return not (dontimgban[cate] == slot)
end


function c_mana:LeftClick(btn, cate, slot)
    local prefab = self:GetBtnSlotData(cate, slot).prefab
    if cate == "light" and slot == "slot" then
        if not prefab then return c_mana:DragFn(btn, cate, slot) end
        local light = p_util:IsEquipped(prefab)
        if light then 
            if p_util:CanTakeItem(light, true) then
                p_util:UnEquip(light)
            end
        else
            light = p_util:GetItemFromAll(prefab, nil, function(item) 
                return e_util:GetItemEquipSlot(item)
                and p_util:GetInvAction(item, true, "equip")
            end, "hands")
            if light then
                p_util:Equip(light)
            else
                btn:install({})
            end
        end
    elseif cate == "eat" and slot == "slot" then
        if not prefab then return end
        local food = p_util:GetItemFromAll(prefab, nil, function(ent) 
            return p_util:GetInvAction(ent, true, "eat") 
        end, "hands")
        if food then
            p_util:Eat(food)
        else
            btn:install({})
        end
    else
        btn.value = not btn.value
        btn:install()
    end
end

function c_mana:RightClick(btn, cate, slot)
    local prefab = self:GetBtnSlotData(cate, slot).prefab
    if cate == "light" and slot == "slot" then
        local lights = p_util:GetItemsFromAll(nil, nil, function(ent)
            return e_util:IsLightSourceEquip(ent) and e_util:GetPercent(ent)>0
        end, "hands")
        local light = e_util:GetNextEntWithPrefab(lights, prefab)
        if light then btn:install(light, true) end
    elseif cate == "eat" and slot == "slot" then
        local foods = p_util:GetItemsFromAll(nil, nil, function(ent) 
            return p_util:GetInvAction(ent,true,"eat") 
        end, "hands")
        local food = e_util:GetNextEntWithPrefab(foods, prefab)
        if food then btn:install(food, true) end
    else
        local equips = p_util:GetItemsFromAll(nil, nil, function(item) 
            -- 这里有个坑，装备栏已经装备的物品没有装备动作
            return e_util:GetItemEquipSlot(item) == slot
        end, "hands")
        -- 注意，这个prefab只是信号量，允许这里什么都不设置的意思
        table.insert(equips, {prefab = "null_huxi"})
        local equip = e_util:GetNextEntWithPrefab(equips, prefab)
        if equip then btn:install(equip, true) end
    end
end


function c_mana:DragFn(btn, cate, slot)
    local active_item = p_util:GetActiveItem()
    if active_item then
        -- 从装备栏拖动，返还到装备栏
        if not p_util:GetEquip(e_util:GetItemEquipSlot(active_item)) and p_util:GetLastUnequip() == active_item then
            p_util:Equip(active_item)
        else
            p_util:ReturnActiveItem(true)
        end
        local flag
        if cate == "light" then
            flag = e_util:GetItemEquipSlot(active_item)
        elseif cate == "eat" then
            flag = p_util:GetInvAction(active_item,true,"eat") 
        else
            flag = e_util:GetItemEquipSlot(active_item) == slot
        end
        if flag then
            btn:install(active_item, true)
        end
    end
end
return c_mana